#pragma once
#include "stdafx.h"

/*======================================================================*/
/*						 Event Manager */
/*======================================================================*/

/* ***********
 * PRIVATE *
 ************/

TEvent::TEvent()
{
	if (_HEAD_EVENT==0)
	{
		_HEAD_EVENT	=	this;
		_prev		=	0;
	}
	else
	{
		_TAIL_EVENT->_next=this;
		_prev		=	_TAIL_EVENT;
	};
	_TAIL_EVENT		=	this;
	_next			=	0;
	_mEventStackCount++;
};

TEvent::TEvent(int Event_Id,int Event_X,int Event_Y,char* Event_Data,int Event_Source)
{
	_id		=	Event_Id;
	_x		=	Event_X;
	_y		=	Event_Y;
	_data	=	Event_Data;
	_src	=	Event_Source;
	
	if (_HEAD_EVENT==0)
	{
		_HEAD_EVENT	=	this;
		_prev		=	0;
	}
	else
	{
		_TAIL_EVENT->_next=this;
		_prev		=	_TAIL_EVENT;
	};
	_TAIL_EVENT		=	this;
	_next			=	0;
	_mEventStackCount		++;
};

TEvent::~TEvent()
{
	if (this==_mCURRENTEVENT) _mCURRENTEVENT=0;
	
	if (this==_HEAD_EVENT)
	{
		if (this==_TAIL_EVENT)
		{
			_HEAD_EVENT=0;
			_TAIL_EVENT=0;
			_mCURRENTEVENT=0;
		}
		else
		{
			_HEAD_EVENT=_HEAD_EVENT->_next;
			_HEAD_EVENT->_prev=0;
		};
	}
	else
	{
		if (this==_TAIL_EVENT)
		{
			_TAIL_EVENT=_TAIL_EVENT->_prev;
			_TAIL_EVENT->_next=0;
		}
		else
		{
			_next->_prev=_prev;
			_prev->_next=_next;
		};
	};
	_mEventStackCount--;
};

int TEvent::Id(){return _id;};
int TEvent::X(){return _x;};
int TEvent::Y(){return _y;};
int TEvent::Source(){return _src;};
const char* TEvent::Data(){return _data;};


void _DeleteEvent (TEvent * ev)
{
	if (ev==0) return;
	delete ev;
};


void EvEmit(int Event_Id,int Event_X,int Event_Y,char* Event_Data,int Event_Source)
{TEvent*e=new TEvent(Event_Id,Event_X,Event_Y,Event_Data,Event_Source);};

int EvPoll()
{
	// remove last interpreted event
	if (_mCURRENTEVENT!=0)
	{
		_DeleteEvent (_mCURRENTEVENT);
	};
	
	if (_HEAD_EVENT==0)	{_mEventStackCount=0;return 0;};

	if (_mEventEnableStack>0)
	{
		while(_mEventStackCount>_mEventStackSize)
		{
			if (_HEAD_EVENT==0)
			{
				_mEventStackCount=0;
				break;
			};
			_DeleteEvent (_HEAD_EVENT);
		};
	};
	
	if (_HEAD_EVENT==0)	{_mEventStackCount=0;return 0;};
	
	_mCURRENTEVENT=_HEAD_EVENT;
		
	return (_HEAD_EVENT!=0);
};


int EvId()    {if (_mCURRENTEVENT!=0){return _mCURRENTEVENT->Id();};return 0;};
int EvX()     {if (_mCURRENTEVENT!=0){return _mCURRENTEVENT->X();};return 0;};
int EvY()     {if (_mCURRENTEVENT!=0){return _mCURRENTEVENT->Y();};return 0;};
int EvSource(){if (_mCURRENTEVENT!=0){return _mCURRENTEVENT->Source();};return 0;};
const char* 
EvData()      {if (_mCURRENTEVENT!=0){return _mCURRENTEVENT->Data();};return "";};

void EvEnableStack(int state){_mEventEnableStack=(state!=0);};
int EvStackEnabled(){return(_mEventEnableStack!=0);};
void SetEvStackSize(int Size){_mEventStackSize=Size;};
int EvStackSize(){return _mEventStackSize;};
int CountEv(){return _mEventStackCount;};